import { isFunction } from '@/utils/type.js';
import { delay } from '@/utils/tools.js'
import http from '@/common/request.js';
import { apiOptions } from '@/api/index.js'

// 配置
const pageConfig = {
  pageKey: 'page',    // 传递给后端的   当前页 key
  pageSizeKey: 'limit',   // 传递给后端放  页大小 key
  pageSize: 20,   // 没有大小
};


const pageMixin = {
	page: { 
		data() {
			return {
				page: 1,   // 当前页
				pageSize: pageConfig.pageSize || 20,  // 每页条数
				status: 'wait',   // 加载状态
				showLoading: true,   // 是否显示
				datas: [],   // 页面列表数据
				pageApi: '',   // 接口
        pageRequestObject: null,    // 页面请求对象
			}
		},
		computed: {
			// 请求发送数据（默认包含page和pageSize）
			reqData() {
				return {
					
				}
			}
		},
		methods: {
			getPage(api) {
				if(api) this.pageApi = api;   // 设置分页接口
				
				if (this.status === 'loading' ||  this.status === 'null' || this.status === 'noMore') return;
        
				this.status = 'loading';   // 改为加载状态
        
				let page = this.page;  // 保存当前请求页
				
				// 默认请求数据
				let def = {
					[pageConfig.pageKey]: page,
          [pageConfig.pageSizeKey]: this.pageSize
				}
        
        // 清酒数据
				let datas = Object.assign({}, def, this.reqData);
        
        // 发送请求，保留请求对象，方便取消
				this.pageRequestObject = this.$$a[this.pageApi](datas);
        
        // 请求结果处理
        this.pageRequestObject.then(res => {
          
					this.pageCallback(res);  // 调用回调函数
					
					// 没有数据
					if (res.count == 0) {
						this.status = 'null';
						this.$nextTick(function() {
							this.$forceUpdate();
						});
						return;
					}
					
					// 第一页初始化数据 , 其他增加
					if (page == 1) {
						this.datas = [];
						this.$nextTick(function(){
							this.datas = res.data;
						})
					} else {
						this.datas = this.datas.concat(res.data);
					}
          
          // 没有下一页数据了
          if (!res.nextpage) {
          	this.status = 'noMore';
          	if (page == 1) {
          		this.showLoading = false;
          	}
          } else {
            // 页数增加
            this.page = page + 1;
            this.status = 'wait';
          }
					
					// 刷新页面
					this.$nextTick(function() {
						this.$forceUpdate();
					});
					
				}).catch(err => {
          console.log(err);
          if(err.errMsg !== 'request:fail abort') {  // 非取消请求导致的失败
            this.status = 'error';
            this.$nextTick(() => {
              this.$forceUpdate();
            });
            this.errCallback(err)
          }
				})
			},
			
			// 重置获取分页
			resetPage() {
        if(isFunction(this.pageRequestObject?.abort)) {
          this.pageRequestObject.abort();   // 进行中的请求
        }
				this.page = 1;
				this.showLoading = true;
				this.status = 'wait';
				this.datas = [];
				this.getPage();
				this.resetPageCallback();
			},
			
			// 获取到分页数据回调
			pageCallback() {
			
			},
			
			// 重置回调
			resetPageCallback() {
				
			},
			
			// 错误回调
			errCallback(err) {
				
			},
			
			// 刷新回调
			refreshCallback() {
				
			},
      
      // 页面返回回调
      backPress() {
        return false;
      }
		},
		
		// 到底加载下一页
		onReachBottom() {
      if(this.pageApi) {
        this.getPage();
      }
		},
		
		// 下拉重新加载
		onPullDownRefresh() {
			this.resetPage();
			this.refreshCallback();
		},
    
    // 退出当前页面，取消请求
    onBackPress() {
      if(isFunction(this.pageRequestObject?.abort)) {
        this.pageRequestObject.abort();   // 进行中的请求
      }
      return this.backPress();
    }
	},
	
	// 同上的不再解释（多个切换列表）
	pages: {
		data() {
			return {
				current: 0,
				navId: 0,
				pageSize: pageConfig.pageSize || 20,
				navs: [],  // 导航
				datas: [],
				pageApi: '',
				lazy: true,   // 是否缓存  （每次切换不在重新获取）
        lazyNum: 99,   // 缓存个数
			}
		},
		computed: {
			reqData() {
				return {
					
				}
			}
		},
		methods: {
			
			// 点击导航
			onnavtap(current) {
			  this.onswiperchange({detail: { current }});
			},
			
			// 滑动swiper
			onswiperchange(e) {
			  const prevCurrent = this.current;
			  
			  let index = e.target?.current || e.detail?.current;
			  this.current = index;
        
        // 非懒加载模式，重置上一页数据。
        if(!this.lazy) {
          handleNav(this.navs[prevCurrent]);
          setTimeout(() => {
            this.datas[prevCurrent] = [];
          }, 250);
          this.resetPage();
          
        // 懒加载模式，没有获取过，则获取数据。
        } else {
          if(this.navs[this.current].isFirst) {
            this.getPage(); 
          }
        }
			},
			
			// 获取导航数据
			getNavs(navApi, pageApi, data = {}) {
				if(!navApi) {
					this.navs = handleNavs(this.navs);
					this.getPage(pageApi);
					return;
				}
				this.$$a[navApi](data).then(res => {
					this.getNavsCallback(res);
					this.navs = handleNavs(res.data);
					this.getPage(pageApi);
				}).catch(err => {})
			},
			
			// 获取分页数据
			async getPage(api) {
				if(api && this.$$t.isString(api)) this.pageApi = api;
				
				let current = this.current;
				let nav = this.navs[current]
				this.navId = nav.id;
				let page = nav.page;
				
        if (nav.status === 'loading' ||  nav.status === 'null' || nav.status === 'noMore') return;
        
				nav.status = 'loading';
        
        await delay(400);   // 延迟一秒发送请求，减少请求频率，优化页面展示（网速过快，导致的加载动画闪烁）。
        
        // 延时结束时若不在本页则不再请求。
        if(current != this.current) {
          nav.status = 'wait';
          return;
        }
				
				// 请求数据
				let def = {
					[pageConfig.pageKey]: page,
					[pageConfig.pageSizeKey]: this.pageSize
				}
				let datas = Object.assign({}, def, this.reqData);
				this.$$a[nav.api || this.pageApi](datas).then(res => {
					
					this.pageCallback(res);
					
					nav.isFirst = false;
					
					// 没有数据
					if (res.count == 0) {
						nav.status = 'null';
						this.$nextTick(function() {
							this.$forceUpdate();
						});
						return;
					}
					
					// 第一页初始化数据 , 其他增加
					if (page == 1) {
            this.$set(this.datas, current, res.data);
					} else {
						this.datas[current] = this.datas[current].concat(res.data);
					}
          
          // 没有下一页数据了
          if (!res.nextpage) {
          	nav.status = 'noMore';
          	if (page == 1) {
          		nav.showStatus = false;
          	}
          } else {
            // 页数增加.
            nav.page = page + 1;
            //延迟执行，防止页面未渲染完成，加载状态已改变。
            setTimeout(() => {
              nav.status = 'wait';
              this.$forceUpdate();
            }, 350)
          }
          
          if(page == 1 && this.lazy) this.handlePageDatas();  // 缓存处理
          
          this.$forceUpdate();
					
				}).catch(err => {
					console.log(err);
					if(err.errMsg !== 'request:fail abort') {  // 非取消请求导致的失败
					  nav.status = 'error';
					  this.$nextTick(() => {
					    this.$forceUpdate();
					  });
					  this.errCallback(err)
					}
					
				})
			},
			
			// 重置获取分页
			resetPage() {
        if(this.pageApi) http.cancelUrlRequest(this.pageApi);
				let current = this.current;
				let nav = this.navs[current]
				nav.page = 1;
				nav.showLoading = true;
				nav.status = 'wait';
        // 懒加载模式，刷新时，仅清除当前页数据
				if(this.lazy) {
          this.datas[current] = [];
          
        // 非懒加载模式，刷新时，取消其他请求
				} else {
          if(this.pageApi) http.cancelUrlRequest(apiOptions[this.pageApi]?.url);
        }
				this.getPage();
				this.resetPageCallback();
			},
      
      // 处理页面数据缓存
      handlePageDatas() {
        if(this.lazyNum > this.navs.length) return;
        const current = this.current;
        const lazyNum = this.lazyNum;
        const start = current - lazyNum;
        const end = current + lazyNum;
        for(let i = 0; i < this.datas.length; i ++) {
          if((i <= start || i >= end) && this.datas[i].length) {
            this.datas[i] = [];
            handleNav(this.navs[i]);
          }
        }
      },
			
			// 获取分类回调
			getNavsCallback() {
				
			},
			
			// 获取到分页数据回调
			pageCallback() {
			
			},
			
			// 刷新回调
			resetPageCallback() {
				
			},
			
			// 错误回调
			errCallback(err) {
				
			},
      
      // 页面返回回调
      backPress() {
        return false;
      }
		},
		
		
		// 下拉重新加载
		onPullDownRefresh() {
			this.resetPage();
		},
    
    // 退出当前页面，取消请求
    onBackPress() {
      if(this.pageApi) http.cancelUrlRequest(apiOptions[this.pageApi]?.url);
      return this.backPress();
    }
	},
}

module.exports = pageMixin;

/**
 * 扩展处理导航。（使用vf-tabbar+swiper+vf-loading做多标签分页时使用）
 * @param {Array} navs 要处理的原导航数组 
 * @param {Function} extendFun  在默认扩展的基础上再扩展，传入一个返回值为对象的函数。
 * @return {Array} 处理后的对象。
 * @example navs = handleNavs(navs);
 * @example navs = handleNavs(navs, () => ({a: [1,2,3]}));
 * */
export function handleNavs(navs, extendFun) {
  return navs.map((item, index) => {
    let extendObject = {};
    if(isFunction(extendFun)) extendObject = extendFun() || {};
    return {
      ...item,
      idx: index,
      status: 'wait',
      showLoading: true,
      page: 1,
      pageSize: pageConfig.pageSize || 20,
      isFirst: true,
      ...extendObject,
    }
  });
}

function handleNav(nav) {
  nav.page = 1;
  nav.status = 'wait';
  nav.showLoading = true;
  nav.isFirst = true;
}